/*============================================================================

     material.cpp  -  Copyright (C) 1993-2005 by Don Cross

     Contains non-linear transformation lookup table for
     material on a chess board.

     This is important for implementing a bonus for trading when
     ahead in material, and a penalty for trading when behind in
     material.

============================================================================*/

#include <math.h>

#include "chess.h"

#define  INITIAL_MATERIAL       \
  (KING_VAL + QUEEN_VAL + 2*ROOK_VAL + 2*BISHOP_VAL + 2*KNIGHT_VAL + 8*PAWN_VAL)

#define  MAX_MATERIAL_POSSIBLE   \
  (KING_VAL + 9*QUEEN_VAL + 2*ROOK_VAL + 2*BISHOP_VAL + 2*KNIGHT_VAL)


SCORE MaterialData [MAX_MATERIAL_POSSIBLE + 1];


SCORE MaterialEval ( SCORE wmaterial, SCORE bmaterial )
{
#if 0
    if (   wmaterial < KING_VAL 
        || wmaterial > MAX_MATERIAL_POSSIBLE 
        || bmaterial < KING_VAL 
        || bmaterial > MAX_MATERIAL_POSSIBLE )
    {
        ChessFatal ( "Invalid material value in MaterialEval()" );
    }
#endif

   return MaterialData[wmaterial] - MaterialData[bmaterial];
}


class MaterialDataInitializer
{
public:
    MaterialDataInitializer();
};


MaterialDataInitializer::MaterialDataInitializer()
{
    SCORE x;

    const double D = 1.4;   // slope at queen down from init material

    const double A = (D - 1.0) / (2.0 * INITIAL_MATERIAL);
    const double B = 0.5 / A + INITIAL_MATERIAL;
    const double C = 0.25 / A + INITIAL_MATERIAL;

    for ( x=KING_VAL; x <= MAX_MATERIAL_POSSIBLE; x++ )
    {
        double g = -A * (x - B) * (x - B) + C;
        MaterialData[x] = SCORE ( 10.0 * g + 0.5 );
    }
}

static MaterialDataInitializer bob;   // Bob loves you!!!
